package clientmgl;

import java.awt.BorderLayout;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Stack;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;

import objects.SpetialFeature;
import objects.WorldObject;
import constants.*;
import extra.Position;


public class MainFrame extends JFrame{
	
	private IdDialog idDialog;
	
	private int clientId;
	
	
	static final String HOST = "localhost"; 
	static final int PUERTO=4999; //puerto en el cual recibe el servidor
	Socket skClient;             //socket mediante el cual me conecto al servidor 
	DataInputStream inputStream; 
	DataOutputStream outputStream;
	
	Stack<Integer> parametersStack = new Stack();
	String parametersMessage = null;
	
	ClientMGL clientMGL;
	private Inventory inventory;
	private PopUpInteraction popUp=null;
	
	private String agentName;
	private int objectID=-1;
	private int objectInventoryId=-1;
	
	public MainFrame(){
		idDialog= new IdDialog(this);
		idDialog.getButtonOk().addActionListener(new IdDialogButtonOkClicked());
		popUp= new PopUpInteraction();
		setLayout(new BorderLayout());
		setVisible(true);
		setSize(new Dimension(400,400));
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
	
	public void createGUI(DataInputStream dataInput , DataOutputStream dataOutput, int clientId){
		clientMGL = new ClientMGL(dataInput, dataOutput, clientId,this);
		inventory= new Inventory(dataOutput,this);
//		clientMGL.setInventory(inventory);
		inventory.setClientMGL(clientMGL);
		
		
		add(clientMGL,BorderLayout.CENTER);
		add(inventory,BorderLayout.WEST);
		
		setSize(getHeight()-1,getWidth()-1);
	}
	
	
	public static void main(String[] args) {
		MainFrame f = new MainFrame();
	}
	

	
	private class IdDialogButtonOkClicked implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent arg0) {
			
			try {
				skClient = new Socket( HOST , PUERTO );
			
				InputStream aux = skClient.getInputStream();
				//genera el flujo de entrada, por aca RECIBO los mensajes que envie el servidor
				inputStream = new DataInputStream( aux );
				
				OutputStream aux1 = skClient.getOutputStream();
				//genera el flujo de salida, por aca se ENVIAN los menajes al servidor
				outputStream = new DataOutputStream( aux1 );
				
				clientId = idDialog.getClientId();
				
				createGUI(inputStream, outputStream, clientId);
				
				//Creo un hilo que escuche los mensajes del servidor
				Runnable escuchaServidor = new HiloEscuchaServidor();
				Thread hiloEscucha = new Thread(escuchaServidor);
				hiloEscucha.start();
				
				String message = Message.CONNECTION_ID+System.getProperty("line.separator")+clientId;
				outputStream.writeUTF(message);
				
				
			} catch (UnknownHostException e) {
				
				e.printStackTrace();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
			
			
		}
		
	} 
	
private class HiloEscuchaServidor implements Runnable{
		
		int idMensaje;
		String msg;
		int head;
		
		@Override
		public void run() {
			//escucho permanentemente los mensajes del servidor
			
			Runnable threadRequestInventory = new ThreadRequestInventoryObjects();
			Thread threadInventory = new Thread(threadRequestInventory);
			threadInventory.start();
			
			while(true){
				
					
					try {
						String msg =inputStream.readUTF().toString();
						//System.out.println("MIRA: "+msg);
						String splt[]=msg.split(System.getProperty("line.separator"));
						head=Integer.parseInt(splt[0]);
						
						switch(head){
						
						case Message.UPDATE_OBJECTS_WORLD:
							clientMGL.generateObjects(splt);
							
						break;
						case Message.AGENTS_FROM_OBJECT:
							clientMGL.generatePopUp(splt);
						break;
						case Message.AGENTS_FROM_OBJECT_INVENTORY:
							//System.out.println("agents from object main frams");
							inventory.generatePopUp(splt);
						break;
						case Message.PARAMETERS_FOR_AGENT:
							//System.out.println("Me enviaron los paremtros");
							//System.out.println(msg);
							generateParameterStack(splt);
						break;
						case Message.DONT_DO_ANYTHING:
							//System.out.println("no hice nada");
						break;
						case Message.INVENTORY_FROM_OBJECT:
							//System.out.println("Estos son los objetos que tengo: "+msg);
							inventory.setObjects(splt);
						break;
						case Message.CONNECTION_ACCEPTED:
							//createGUI(inputStream, outputStream, clientId);
							idDialog.setVisible(false);
						break;
						case Message.BACKGROUND_OBJECT:
							clientMGL.setBackgroundObject(splt);
							clientMGL.clearScreen();
						break;
						case Message.CONNECTION_REFUSSED:
							//System.out.println("CONECCION RECHAZADA");
						break;
						case Message.DIALOG_TO_SHOW:
							//System.out.println("RECIBI UN DIALOGO QUE MOSTRAR ");
							//System.out.println(splt[1]);
							generateDialog(splt);
							
						break;
						case Message.POSITION_CAMERA:
							double x = Double.parseDouble(splt[1]);
							double y = Double.parseDouble(splt[2]);
							clientMGL.setCameraPosition(x,y);
						break;
						case Message.CLIENT_UNIVERSE_TRANSPORT:
							int universeId = Integer.parseInt(splt[1]);
							//System.out.println("ACCCCCCACACACA MAIN FRAME"+splt[1]);
							String message = Message.CLIENT_UNIVERSE_TRANSPORT + System.getProperty("line.separator")+universeId;
							outputStream.writeUTF(message);
							//System.out.println(message);
							//clientMGL.clearScreen();
							
							
						break;
						default:
							
							System.out.println("CABECERA DE MENSAJE DESCONOCIDA cliente ");
							System.out.println(msg);
						
						}
						
						
						
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
			
			repaint();
				
			}
		}

		

	}
	private void generateDialog(String[] splt) {
		JDialog dialog = new JDialog();
		JLabel label = new JLabel(splt[1]);
		dialog.add(label);
		dialog.setSize(new Dimension(200,200));
		dialog.setLocation(this.getWidth()/3, this.getHeight()/3);
		dialog.setVisible(true);
		
	}
	public void sendAgentChosed(String str) {
		try {
		String s = new String();
		agentName=str;
		 s = Message.ASK_FOR_PARAMETERS+System.getProperty("line.separator")+objectID+";"+str;
		 
		
		outputStream.writeUTF(s);
		
		System.out.println(s);
		System.out.println("SELECCIONE "+str);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	public void generatePopUp(String[] splt, int x, int y, int objectID) {
		this.objectID=objectID;
		popUp = new PopUpInteraction(splt, this);
		popUp.show(this, x, y);
		
		
	}
	
	public void generateParameterStack(String[] splt) {
		parametersStack= new Stack();
		String parameters [] = splt[1].split(";");
		Stack<Integer> stack = new Stack();
		for(int i =0 ; i<parameters.length; i++){
			stack.push(Integer.parseInt(parameters[i]));
		}
		while(!stack.isEmpty()){
			parametersStack.push(stack.pop());
		}
		clientMGL.setState(Constants.PARAMETERS_FOR_ACTION);
		inventory.setState(Constants.PARAMETERS_FOR_ACTION);
		parametersMessage = new String();
		parametersMessage = Message.SEND_PARAMETERS_FOR_AGENT+System.getProperty("line.separator")+objectID+"/"+agentName;
	}


	public Stack<Integer> getParametersStack() {
		return parametersStack;
	}


	public void setParametersStack(Stack<Integer> parametersStack) {
		this.parametersStack = parametersStack;
	}


	public String getParametersMessage() {
		return parametersMessage;
	}


	public void setParametersMessage(String parametersMessage) {
		this.parametersMessage = parametersMessage;
	}
	
	public void setState(int state){
		inventory.setState(state);
		clientMGL.setState(state);
	}
	public void setObjectInventoryId(int id){
		this.objectInventoryId=id;
		String message=Message.REQUEST_INVENTORY+System.getProperty("line.separator")+objectInventoryId;
		try {
			outputStream.writeUTF(message);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private class ThreadRequestInventoryObjects implements Runnable{

		@Override
		public void run() {
			
			String message = new String();
			
			while(true){
				try {
					
					Thread.sleep(500);
					if(objectInventoryId!=constants.Constants.NO_OBJECT_ID){
						message=Message.REQUEST_INVENTORY+System.getProperty("line.separator")+objectInventoryId;
						outputStream.writeUTF(message);
					}
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}

public static WorldObject createObject(String str) {
		
		WorldObject obj = new WorldObject();
		
		String splt[]=str.split(";");
		obj.setObjectReference(Integer.parseInt(splt[0]));
		
	    obj.getImageObject().setImageToShow(ImagesSingleton.images[obj.getObjectReference()]); //TODO 

		double x =Double.parseDouble(splt[1]);
		double y =Double.parseDouble(splt[2]);
		//obj.getImageObject().setPosition(new Position(x,y));
		obj.setPosition(new Position(x,y));
		/*obj.imageObject.getPosition().setX(Double.parseDouble(splt[1]));
		obj.imageObject.getPosition().setY(Double.parseDouble(splt[2]));*/
		
		
		Boolean isActive=Boolean.parseBoolean(splt[3]);
		obj.setActive(isActive);
		int ID=Integer.parseInt(splt[4]);
		obj.setID(ID);
		int owner=Integer.parseInt(splt[5]);
		obj.setOwner(owner);
		int isBackground=Integer.parseInt(splt[6]);
		obj.setIsBackground(isBackground);
		
		for(int i = 7 ; i<splt.length;i++){
			SpetialFeature feature = new SpetialFeature();
			feature.setId(Integer.parseInt(splt[i]));
			i++;
			feature.setName(splt[i]);
			i++;
			feature.setValue(Double.parseDouble(splt[i]));
			obj.addSpetialFeature(feature);
		}
		
		return obj;
	}
	
}
